package com.comleader.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.comleader.entity.hopper.Global;
import com.comleader.entity.hopper.Hopper;
import com.comleader.entity.Point;
import com.graphhopper.GHRequest;
import com.graphhopper.GHResponse;
import com.graphhopper.GraphHopper;
import com.graphhopper.PathWrapper;
import com.graphhopper.reader.osm.GraphHopperOSM;
import com.graphhopper.routing.util.EncodingManager;
import com.graphhopper.util.GPXEntry;
import com.graphhopper.util.shapes.GHPoint;
import org.springframework.beans.factory.annotation.Value;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * @author ：杨浩毅 (1759)
 * @date ：2020/9/8 17:20
 */
public class HopperUtils {
    /**
     * 路网数据源
     * @return 经过路径规划算法算过的文件位置
     */
    public static GraphHopper DataSource(Hopper hopper){
        // 创建一个GraphHopper实例
        GraphHopper ghhopper = new GraphHopperOSM().forServer();
        ghhopper.setDataReaderFile("D:/Route/china-latest.osm.pbf");
        // 在哪里存储graphhopper文件？
        String path="Data/fastest/"+hopper.getVehicle();
        ghhopper.setGraphHopperLocation(path);
        ghhopper.setEncodingManager(new EncodingManager(hopper.getVehicle()));
        // 现在，如果导入，则可能需要几分钟，或者加载需要几秒钟
        // 当然这取决于您导入的区域
        ghhopper.importOrLoad();
        return ghhopper;
    }

    /**
     * 坐标点集合的路线规划
     * @param ghPoints 坐标点集合
     * @param hopper 路径规划配置信息
     * @return 路径规划对象
     */
    public static PathWrapper path(List<GHPoint> ghPoints,Hopper hopper){
        GHRequest req = new GHRequest(
                ghPoints).
                setWeighting(hopper.getWeighting()).
                setVehicle(hopper.getVehicle()).
                setLocale(Locale.CHINA);
        GHResponse rsp = DataSource(hopper).route(req);
        // 首先检查错误
        if (rsp.hasErrors()) {
            rsp.getErrors();
        }
        // 使用最佳路径，请参阅GHResponse类以了解更多可能性。
        PathWrapper path = rsp.getBest();
        return path;
    }

    /**
     * 传输过来的坐标集合从GCJ-02坐标系转化为WGS-84坐标系
     * GCJ-02为火星坐标系（高德坐标系、谷歌坐标系）
     * WGS-84为地球坐标系（osm坐标系）
     * @param list 前端传过来的坐标点集合（JSON格式）
     * @return 转化为WGS-84坐标系的JSON格式坐标集合
     */
    public static String Gaodepoints(String list){
        List<GHPoint> points= JSONArray.parseArray(list,GHPoint.class);
        Map<String, Double> stringDoubleMap =null;
        List<Point> pointLs=new ArrayList<>();
        for (GHPoint point : points) {
            stringDoubleMap = TransLocationUtil.gcj2wgs(point.getLon(), point.getLat());
            List<Double> listlon = new ArrayList<>();
            List<Double> listlat = new ArrayList<>();
            for (String s1 : stringDoubleMap.keySet()) {
                Double lon =null;
                Double lat =null;
                if (s1.equals("lon")){
                    lon = stringDoubleMap.get(s1);
                    listlon.add(lon);
                }else {
                    lat = stringDoubleMap.get(s1);
                    listlat.add(lat);
                }
            }
            Point point1 = new Point(listlat.get(0),listlon.get(0));
            pointLs.add(point1);
        }
        String s1 = JSON.toJSONString(pointLs);
        String s2 = s1.replaceAll("lng", "lon");
        return s2;
    }
    /**
     * 使用百度地图坐标系的
     * BD-09百度坐标系转化为WGS-84
     */
    public static String Baidupoints(String s){
        List<GHPoint> points= JSONArray.parseArray(s,GHPoint.class);
        Map<String, Double> stringDoubleMap =null;
        //第一次转换坐标系BD-09转化为GCJ-02
        List<Point> pointLs=new ArrayList<>();
        for (GHPoint point : points) {
            stringDoubleMap = TransLocationUtil.bd09_to_gcj02(point.getLon(), point.getLat());
            List<Double> listlon = new ArrayList<>();
            List<Double> listlat = new ArrayList<>();
            for (String s1 : stringDoubleMap.keySet()) {
                Double lon =null;
                Double lat =null;
                if (s1.equals("lon")){
                    lon = stringDoubleMap.get(s1);
                    listlon.add(lon);
                }else {
                    lat = stringDoubleMap.get(s1);
                    listlat.add(lat);
                }
            }
            Point point1 = new Point(listlat.get(0),listlon.get(0));
            pointLs.add(point1);
        }
        List<Point> pointList=new ArrayList<>();
        for (Point pointL : pointLs) {
            Map<String, Double> stringDoubleMap1 = TransLocationUtil.gcj2wgs(pointL.getLng(), pointL.getLat());
            List<Double> lilon = new ArrayList<>();
            List<Double> lilat = new ArrayList<>();
            for (String s1 : stringDoubleMap1.keySet()) {
                Double lon =null;
                Double lat =null;
                if (s1.equals("lon")){
                    lon = stringDoubleMap.get(s1);
                    lilon.add(lon);
                }else {
                    lat = stringDoubleMap.get(s1);
                    lilat.add(lat);
                }
            }
            Point point1 = new Point(lilat.get(0),lilon.get(0));
            pointList.add(point1);
        }
        String s1 = JSON.toJSONString(pointList);
        String s2 = s1.replaceAll("lng", "lon");
        return s2;
    }
    /**
     * 将算法算过的坐标组转化为GCJ-02坐标系
     * @param list 算法得到的途径坐标集合
     * @return 转化过后的途径坐标集合
     * gpxEntry.ele为算法返回的海拔
     * gpxEntry.getTime()为获取到的前一个点到当前点的时间戳
     */
    public static List GaodegpxList(List<GPXEntry> list){
        List points=new ArrayList<>();
        for (GPXEntry gpxEntry : list) {
            Map<String, Double> transform = TransLocationUtil.transform(gpxEntry.lon, gpxEntry.lat);
            List<Double> llon = new ArrayList<>();
            List<Double> llat = new ArrayList<>();
            for (String s3 : transform.keySet()) {
                Double lon1 =null;
                Double lat1 =null;
                if (s3.equals("lon")){
                    lon1 = transform.get(s3);
                    llon.add(lon1);
                }else {
                    lat1 = transform.get(s3);
                    llat.add(lat1);
                }
            }
            Point point2 = new Point(llon.get(0),llat.get(0),gpxEntry.ele,gpxEntry.getTime());
            points.add(point2);
        }
        return points;
    }
    /**
     * WGS-84转化为BD-09
     * 百度地图返回路径规划坐标
     */
    public static List BaiduGPXList(List<GPXEntry> list){
        List points=new ArrayList<>();
        for (GPXEntry gpxEntry : list) {
            Map<String, Double> transform = TransLocationUtil.wgs84_to_bd09(gpxEntry.lon, gpxEntry.lat);
            List<Double> llon = new ArrayList<>();
            List<Double> llat = new ArrayList<>();
            for (String s3 : transform.keySet()) {
                Double lon1 =null;
                Double lat1 =null;
                if (s3.equals("lon")){
                    lon1 = transform.get(s3);
                    llon.add(lon1);
                }else {
                    lat1 = transform.get(s3);
                    llat.add(lat1);
                }
            }
            Point point2 = new Point(llon.get(0),llat.get(0),gpxEntry.ele,gpxEntry.getTime());
            points.add(point2);
        }
        return points;
    }
}
